package space

import (
	"context"
	"gitee.com/bobo-rs/idea-space-framework/consts"
	"gitee.com/bobo-rs/idea-space-framework/framework/dao"
	"gitee.com/bobo-rs/idea-space-framework/framework/model"
	"gitee.com/bobo-rs/idea-space-framework/framework/service"
	"gitee.com/bobo-rs/idea-space-framework/pkg/utils"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/os/gcache"
	"strconv"
	"time"
)

// SaveSpaceImage 保存设计图片数据
func (s *sSpace) SaveSpaceImage(ctx context.Context, design model.SpaceDetailItem) (sid int64, err error) {
	// 保存数据
	err = dao.SpaceImages.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		r, err := tx.Ctx(ctx).Save(dao.SpaceImages.Table(), design.SpaceImageItem)
		if err != nil {
			return err
		}
		// 获取最新插入ID
		sid, err = r.LastInsertId()
		if err != nil {
			return err
		}
		design.Detail.SpaceId = uint(sid)
		design.Attr.SpaceId = uint(sid)
		// 更新设计空间详情
		_, err = tx.Ctx(ctx).Save(dao.SpaceImagesDetail.Table(), design.Detail)
		if err != nil {
			return gerror.Wrapf(err, `保存设计空间详情失败%s`, err.Error())
		}
		// 更新设计空间属性
		_, err = tx.Ctx(ctx).Save(dao.SpaceImagesAttr.Table(), design.Attr)
		// 创建索引
		_ = service.Label().SaveLabelIdx(ctx, uint(sid), 1, design.Detail.LabelValues)
		return err
	})
	return
}

// IncSpaceDesignBrowse 设计空间增量浏览量
func (s *sSpace) IncSpaceDesignBrowse(ctx context.Context, id uint) error {
	var (
		cacheKey  = utils.CacheKey(consts.DesignIncBrowseLockId, strconv.Itoa(int(id)))
		cacheFunc = func(ctx context.Context) (interface{}, error) {
			err := s.IncSpaceDesign(ctx, []uint{id}, dao.SpaceImages.Columns().Browse, 1)
			return nil, err
		}
	)
	// 缓存锁定
	_, err := gcache.GetOrSetFunc(ctx, cacheKey, cacheFunc, time.Minute)
	return err
}

// IncSpaceDesign 增量设计空间字段数值
func (s *sSpace) IncSpaceDesign(ctx context.Context, id []uint, columns string, amount ...int) error {
	var n = 1
	if len(amount) > 0 {
		n = amount[0]
	}
	return s.IncOrDec(ctx, model.CommonIncOrDecByIdItem{
		Id: id,
		CommonIncOrDecItem: model.CommonIncOrDecItem{
			Amount:  n,
			Columns: columns,
		},
	})
}

// DecSpaceDesign 设计空间减量字段数值
func (s *sSpace) DecSpaceDesign(ctx context.Context, id []uint, columns string, amount ...int) error {
	var n = 1
	if len(amount) > 0 {
		n = amount[0]
	}
	return s.IncOrDec(ctx, model.CommonIncOrDecByIdItem{
		Id: id,
		CommonIncOrDecItem: model.CommonIncOrDecItem{
			Amount:   n,
			Columns:  columns,
			IncByDec: true,
		},
	})
}

// IncOrDec 增量或者减量处理
func (s *sSpace) IncOrDec(ctx context.Context, in model.CommonIncOrDecByIdItem) error {
	if len(in.Id) == 0 || (len(in.Id) > 0 && in.Id[0] == 0) {
		return gerror.New(`缺少设计空间ID`)
	}
	var (
		orm  = dao.SpaceImages.Ctx(ctx).Where(dao.SpaceImages.Columns().Id, in.Id)
		err  error
		text string
	)
	switch in.IncByDec {
	case true:
		// 减量
		text = `减量`
		_, err = orm.Decrement(in.Columns, in.Amount)
	default:
		// 增量
		text = `增量`
		_, err = orm.Increment(in.Columns, in.Amount)
	}
	if err != nil {
		return gerror.Wrapf(err, `%s设计空间%s失败%s`, text, in.Columns, err.Error())
	}
	return nil
}
